package fight.view.armytype
{
	import com.greensock.easing.Linear;
	import com.greensock.TweenMax;
	import fight.FightC;
	import flash.display.Bitmap;
	import flash.display.Sprite;
	import morn.core.components.Clip;
	import org.airmvc.Dispatcher;
	import utils.T;
	
	/**
	 * 基本兵种
	 * @author WLDragon 2014-05-06
	 */
	public class BaseArmy extends Sprite
	{
		
		public function BaseArmy(isAttack:Boolean, hp:int, resName:String, dir:int, attackEffect:Bitmap, callBack:Function)
		{
			//var tf:TextFormat = new TextFormat(null,14);
			//tempBit = new TextField();
			//tempBit.defaultTextFormat = tf;
			//tempBit.background = true;
			//tempBit.backgroundColor = 0xffffff;
			//tempBit.width = 30;
			//tempBit.height = 20;
			//tempBit.x = 5;
			//tempBit.y = 5;
			
			this.isAttack = isAttack;
			this.hp = hp;
			this.attackEffect = attackEffect;
			this.next = callBack;
			
			clip = new Clip(resName, 8, 1);
			addChild(clip);
			
			direction = dir;
			App.timer.doFrameLoop(4, loop);
			
			//addChild(tempBit);
		}
		
		private function loop():void
		{
			if (clip.frame == frame1)
				clip.frame = frame2;
			else
				clip.frame = frame1;
		}
		
		public function work(mapData:Array, targetLeader:BaseArmy):void
		{
			this.mapData = mapData;
			px = this.x / 32;
			py = this.y / 32;
			
			if ((state == 0 || state == 1 || state == 2) && testAttack())
				return;
			
			if (state == 2)
			{
				next.call();
				return;
			}
				
			//后退
			if (state == 3)
			{
				if (isAttack)
					move([{x: px - 1, y: py}, {x: px, y: py + 1}, {x: px, y: py - 1}]);
				else
					move([{x: px + 1, y: py}, {x: px, y: py + 1}, {x: px, y: py - 1}]);
				
				return;
			}
			
			//向着武将前进（获取三个可走方位，按离目标武将的距离来排序）
			var scope:Array = [{x: px, y: py - 1}, {x: px + 1, y: py}, {x: px, y: py + 1}, {x: px - 1, y: py}];
			for each(var o:Object in scope)
			{
				o.distance = Math.pow(targetLeader.x - o.x * 32,2) + Math.pow(targetLeader.y - o.y * 32,2);
			}
			scope.sortOn("distance", Array.NUMERIC);
			scope.pop();//最远那个肯定是后退的，所以不走
			move(scope);
		}
		
		private function move(scope:Array):void
		{
			var ba:BaseArmy;
			for each (var a:Object in scope)
			{
				if (a.x > -1 && a.x < 16 && a.y > -1 && a.y < 9)
				{
					ba = mapData[a.y][a.x];
					if (ba == null)
					{
						mapData[py][px] = null;
						mapData[a.y][a.x] = this;
						direction = judgeDirection(a.x - px, a.y - py);
						TweenMax.to(this, 0.3, { x: a.x * 32, y: a.y * 32 ,ease:Linear.easeNone,onComplete:next} );
						return;
					}
				}
				else
				{
					if (this is Leader)
					{
						Dispatcher.send(FightC.LEADER_ESCAPE_OR_DIE, this);
						parent.removeChild(this);
					}
					else
					{
						mapData[py][px] = null;
						parent.removeChild(this);
						this.state = 4;
					}
					next.call();
					return;
				}
			}
			
			next.call();
		}
		
		protected function getScope():Array
		{
			var scope:Array = [ { x: px, y: py - 1 }, { x: px + 1, y: py }, { x: px, y: py + 1 }, { x: px - 1, y: py } ];
			T.util.radomArray(scope);//随机方向
			return scope;
		}
		
		protected function testAttack():Boolean
		{
			var ba:BaseArmy;
			//获取攻击范围内的对象
			var scope:Array = getScope();
			for each (var a:Object in scope)
			{
				if (a.x > -1 && a.x < 16 && a.y > -1 && a.y < 9)
				{
					ba = mapData[a.y][a.x];
					if (ba)
					{
						if (ba.isAttack != this.isAttack)
						{
							direction = judgeDirection(a.x - px, a.y - py);
							if (ba is Leader)
							{
								if (state == 0 || state == 2)
									attack(ba);
								else
									break;
							}
							else
							{
								attack(ba);
							}
							
							return true;
						}
					}
				}
			}
			
			return false;
		}
		
		protected function attack(target:BaseArmy):void
		{
			attackEffect.visible = true;
			attackEffect.x = target.x + EFFECT_POSITION[direction].x;
			attackEffect.y = target.y + EFFECT_POSITION[direction].y;
			App.timer.doFrameOnce(10, attackOver);
			
			target.beAttack(this);
		}
		
		private function attackOver():void 
		{
			attackEffect.visible = false;
		}
		
		public function beAttack(attacker:BaseArmy):void
		{
			beAttackTimes = 0;
			App.timer.doFrameLoop(2, timeBeAttack,[attacker]);
		}
		
		protected function getFactorB(ahp:int):int
		{
			if (ahp < 0 || ahp > 100)
				return 0;//按逻辑血量少于0的士兵已经移除不可能再进行攻击，但偶尔会出现这样的bug，这里暂时以这种方法屏蔽
				
			var x:XML = T.db.getXml(Cnt.XML_ALGORITHM).hurt.factorB.hp.(@min <= ahp && ahp <= @max)[0];
			return int(x.@value);
		}
		
		private function timeBeAttack(attacker:BaseArmy):void 
		{
			if (beAttackTimes == 6)
			{
				App.timer.clearTimer(timeBeAttack);
				bruise(attacker);
				next.call();
			}
			else
			{
				this.visible = !this.visible;
				beAttackTimes++;
			}
		}
		
		protected function bruise(attacker:BaseArmy):void
		{
			throw new Error("在子类中重写");
		}
		
		protected function judgeDirection(tx:int, ty:int):int
		{
			if (tx > 0)
			{
				return 0;
			}
			else if (ty > 0)
			{
				return 1;
			}
			else if (tx < 0)
			{
				return 2;
			}
			
			return 3;
		}
		
		public function destroy():void
		{
			App.timer.clearTimer(loop);
			clip == null;
		}
		
		public function get direction():int
		{
			return _direction;
		}
		
		/**方向，0-右 1-下 2-左 3-上*/
		public function set direction(value:int):void
		{
			if (value < 0 || value > 3)
				return;
			
			frame1 = value * 2;
			frame2 = frame1 + 1;
			_direction = value;
		}
		
		public function get hp():int 
		{
			return _hp;
		}
		
		public function set hp(value:int):void 
		{
			//tempBit.text = value.toString();
			_hp = value;
		}
		
		public function get state():int 
		{
			return _state;
		}
		
		public function set state(value:int):void 
		{
			if (_state == 4 || _state == 5)
				return;
				
			_state = value;
		}
		
		//private var tempBit:TextField;
		
		private var next:Function;
		protected var mapData:Array;
		protected var px:int;
		protected var py:int;
		private var frame1:int;
		private var frame2:int;
		private var clip:Clip;
		private var _direction:int;
		private var _hp:int;
		public var factorA:int;
		public var factorB:int;
		/**状态 0-前进 1-包围 2-待机 3-后退 4-逃跑 5-死亡（逃跑用于战斗结束后统计总人数 ，后退出屏幕后不能再回来，但实际不会减少武将带兵数量）*/
		private var _state:int = 0;
		/**阵营，是否为进攻方*/
		public var isAttack:Boolean;
		private var attackEffect:Bitmap;
		/**被打时闪烁的次数*/
		private var beAttackTimes:int;
		static public const EFFECT_POSITION:Array = [ { x: -14, y:21 }, { x:2, y: 5 }, { x:18, y:21 }, { x:2, y:37 } ];
	}

}